home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-07-03 | 4.0 KB | 131 lines | [TEXT/R*ch] |
- (* Word -- new basis 1994-11-01, 1995-04-06, 1995-07-12 *)
-
- (* This unit relies on two's complement representation *)
-
- prim_eqtype word;
-
- #include "../config/m.h"
- #ifdef SIXTYFOUR
- #define WORDSIZE 63
- #else
- #define WORDSIZE 31
- #endif
-
- val wordSize = WORDSIZE;
-
- local
- prim_val orb_ : word -> word -> word = 2 "or";
- prim_val andb_ : word -> word -> word = 2 "and";
- prim_val xorb_ : word -> word -> word = 2 "xor";
- prim_val lshift_ : word -> word -> word = 2 "shift_left";
- prim_val rshiftsig_ : word -> word -> word = 2 "shift_right_signed";
- prim_val rshiftuns_ : word -> word -> word = 2 "shift_right_unsigned";
- prim_val adduns_ : word -> word -> word = 2 "+intunsig";
- prim_val subuns_ : word -> word -> word = 2 "-intunsig";
- prim_val muluns_ : word -> word -> word = 2 "*intunsig";
- prim_val divuns_ : word -> word -> word = 2 "divunsig";
- prim_val moduns_ : word -> word -> word = 2 "modunsig";
-
- in
- prim_val wordToInt : word -> int = 1 "identity";
- prim_val signExtend : word -> int = 1 "identity";
- prim_val intToWord : int -> word = 1 "identity";
-
- fun orb (x, y) = orb_ x y;
- fun andb (x, y) = andb_ x y;
- fun xorb (x, y) = xorb_ x y;
- fun notb x = xorb_ x (intToWord ~1);
-
-
- fun << (w, k) =
- if wordToInt k >= WORDSIZE orelse wordToInt k < 0 then intToWord 0
- else lshift_ w k;
-
- fun >> (w, k) =
- if wordToInt k >= WORDSIZE orelse wordToInt k < 0 then intToWord 0
- else rshiftuns_ w k;
-
- fun ~>> (w, k) =
- if wordToInt k >= WORDSIZE orelse wordToInt k < 0 then
- if wordToInt w >= 0 then (* msbit = 0 *)
- intToWord 0
- else (* msbit = 1 *)
- intToWord ~1
- else
- rshiftsig_ w k;
-
- fun w1 + w2 = adduns_ w1 w2;
- fun w1 - w2 = subuns_ w1 w2;
- fun w1 * w2 = muluns_ w1 w2;
- fun w1 div w2 = divuns_ w1 w2;
- fun w1 mod w2 = moduns_ w1 w2;
-
- local
- open StringCvt
- fun skipWSget getc source = getc (skipWS {getc=getc} source)
-
- (* Below, 48 = Char.ord #"0" and 55 = Char.ord #"A" - 10. *)
- fun decval c = intToWord (Char.ord c) - intToWord 48;
- fun hexval c =
- if #"0" <= c andalso c <= #"9" then
- intToWord (Char.ord c) - intToWord 48
- else
- moduns_ (intToWord (Char.ord c) - intToWord 55) (intToWord 32);
-
- fun prhex i =
- if wordToInt i < 10 then Char.chr(wordToInt (i + intToWord 48))
- else Char.chr(wordToInt (i + intToWord 55));
-
- fun conv radix i =
- let fun h n res =
- if n = intToWord 0 then res
- else h (divuns_ n radix) (prhex (moduns_ n radix) :: res)
- fun tostr n = h (divuns_ n radix) [prhex (moduns_ n radix)]
- in String.implode (tostr i) end
-
- in
- fun scan radix {getc} source =
- let open StringCvt
- val (isDigit, factor) =
- case radix of
- BIN => (fn c => (#"0" <= c andalso c <= #"1"), 2)
- | OCT => (fn c => (#"0" <= c andalso c <= #"7"), 8)
- | DEC => (Char.isDigit, 10)
- | HEX => (Char.isHexDigit, 16)
- fun dig1 NONE = NONE
- | dig1 (SOME (c, rest)) =
- let fun digr res src =
- case getc src of
- NONE => SOME (res, src)
- | SOME (c, rest) =>
- if isDigit c then
- digr (intToWord factor * res + hexval c) rest
- else
- SOME (res, src)
- in
- if isDigit c then digr (hexval c) rest
- else NONE
- end
- in dig1 (skipWSget getc source) end;
-
- fun fmt BIN = conv (intToWord 2)
- | fmt OCT = conv (intToWord 8)
- | fmt DEC = conv (intToWord 10)
- | fmt HEX = conv (intToWord 16)
-
- fun toString w = conv (intToWord 16) w
- fun fromString s = scanString (scan HEX) s
- end (* local for string functions *)
-
- val op > = fn (w1, w2) =>
- if wordToInt w1 >= 0 then
- wordToInt w2 >= 0 andalso wordToInt w1 > wordToInt w2
- else
- wordToInt w2 >= 0 orelse wordToInt w1 > wordToInt w2;
- fun w1 < w2 = w2 > w1;
- fun w1 >= w2 = not (w1 < w2);
- fun w1 <= w2 = not (w1 > w2);
- fun compare (x, y: word) =
- if x<y then LESS else if x>y then GREATER else EQUAL;
- end
-